React - state en levenscyclus
Home

React - state en levenscyclus

React - state en levenscyclus

React-componenten hebben een ingebouwd state object. Daarin worden eigenschapswaarden opgeslagen die bij de component horen. Wanneer het state object gewijzigd wordt, wordt de component opnieuw weergegeven (re-rendered).

Ouder- of kindcomponenten kunnen weten niet of een bepaald component stateful of stateless is. Zij weten ook niet of een component wordt gedefinieerd als een functie of een klasse.

Het state object is dus lokaal of ingekapseld in de klasse waartoe het behoort en het is niet toegankelijk voor andere componenten.

Doelstelling

Het state object heeft twee doelstellingen die met elkaar nauw verbonden zijn. Het dient om gegevens over de component bij te houden en dient als trigger om de component opnieuw weer te geven (re-rendering).

Als voorbeeld gaan we een like-knop aan de Marvel-component toevoegen. Maar wel op die manier dat we de like-knop ook in een andere app kunnen gebruiken. We gaan er dus een op zichzelf staande component van maken, opmaak incluis.

Stappen

  1. De code voor de LikeButton knop plaatsen we in een bestand met de naam UIControls.js.
  2. We maken een klassencomponent die een knop weergeeft:
    class LikeButton extends React.Component {
        render() {
            return <button>{typeof this.props.caption !== 'undefined' 
                ? this.props.caption : 'button'}</button>
        }
    }
  3. En we testen die control in ui-controls.html pagina:
    <!DOCTYPE html>
    <html lang="nl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Snel starten met React</title>
        <!-- Note: when deploying, replace "development.js" with "production.min.js". -->
        <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
        <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
        <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
        <script type="text/babel" src="js/UIControls.js"></script>
    </head>
    <body>
        <div id="root">
            <div id="one"></div>
            <div id="two"></div>
        </div>
        <script type="text/babel">
            ReactDOM.render(
                <div>
                <LikeButton caption="Mijn knop" />
                <LikeButton />
                </div>, 
                document.querySelector('#two'))
        </script>
    </body>  
    </body>
    </html>
    1. We laden het js/UIControls.js bestand en geven me dat het van het type text/babel is.
    2. In de render methode van ReactDOM roepen we de LikeButton klasse met de <LikeButton/> XML notatie van JSX.
    3. We maken gebruik van wat geleerd hebben over props en geven aan de <LikeButton/> XML tag het caption attribuut mee. Dat wordt door JSX omgezet in een props object van de LikeButton klasse. De tweede knop heeft geen caption attribuut en de LikeButton klasse toont dan ook de standaard tekst.
    4. Met dit als resultaat:
      react-bare-button-class
      react-bare-button-class
    5. We voegen wat CSS toe aan de component zelf:
      class LikeButton extends React.Component {
          buttonStyle = {
              boxShadow: "inset 0px 1px 0px 0px #97c4fe",
              background: "linear-gradient(to bottom, #3d94f6 5%, #1e62d0 100%)",
              backgroundColor: "#3d94f6",
              borderRadius: "6px",
              border: "1px solid #337fed",
              display: "inline-block",
              cursor: "pointer",
              color: "#ffffff",
              fontFamily: "Arial",
              fontSize: "15px",
              fontWeight: "bold",
              padding: "6px 24px",
              textShadow: "0px 1px 0px #1570cd"
          }
      
          render() {
              return <button style={this.buttonStyle}>{typeof this.props.caption !== 'undefined'
                  ? this.props.caption : 'button'}</button>
      
          }
      
      }
    6. En dat ziet er al veel beter uit:
      react-button-with-style-class
      react-button-with-style-class
  4. Vermits we een like knop willen maken moet de knop bijhouden hoeveel keren erop geklikt werd. Daarvoor gaan we het ingebouwde state object van React klassencomponenten gebruiken. We declareren het aantal likes in de constructor als een eigenschap van het state object met de naam likes:
    constructor(props) {
        super(props);
        this.state = {
            likes: 0
        };
    
    }
  5. We voegen een incrementLike klikafhandelaar methode aan de klassencomponent toe die het aantal likes met 1 verhoogt telkens wanneer op de knop wordt geklikt:
    incrementLike = () => {
        let newCount = this.state.likes + 1;
        this.setState({
            likes: newCount
        });
    };
  6. We passen de return in de render methode aan:
    1. het aantal likes tonen we in een label en we stijlen het:
      labelStyle = {
          display: "inline-block",
          color: "#ffffff",
          backgroundColor: "#3d94f6",
          textShadow: "0px 1px 0px #1570cd",
          padding: "6px 24px",
          textShadow: "0px 1px 0px #1570cd",
          borderRadius: "6px",
          border: "1px solid #337fed"
      }
    2. de button en het label zetten we in een div
    render() {
        return <div><button onClick={this.incrementLike}
            style={this.buttonStyle}>{typeof this.props.caption !== 'undefined'
                ? this.props.caption : 'button'}</button>
            <label style={this.labelStyle}>{this.state.likes}</label>
        </div>
  7. En we testen die control in ui-controls.html pagina:
    <!DOCTYPE html>
    <html lang="nl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Snel starten met React</title>
        <!-- Note: when deploying, replace "development.js" with "production.min.js". -->
        <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
        <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
        <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
        <script type="text/babel" src="js/UIControls.js"></script>
    </head>
    <body>
        <div id="root">
            <div id="one"></div>
            <div id="two"></div>
        </div>
        <script type="text/babel">
            ReactDOM.render(
                <div>
                <LikeButton caption="I like"/>
                <LikeButton caption="I like"/>
                </div>, 
                document.querySelector('#two'))
        </script>
    </body>  
    </html>
  8. Met dit als resultaat:
    react-like-button-class
    react-like-button-class

JI
2020-04-17 16:36:17